package com.audaque.encoding.coding;

import com.audaque.encoding.dto.FileInfoRes;
import com.audaque.encoding.dto.GetFilepathReq;
import com.audaque.encoding.dto.GetFilepathRes;
import com.audaque.encoding.util.HttpUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;

/**
 * @author mayong
 * @since 2024/3/20
 */
@Component
@Slf4j
public class CoreService {


    @Value("${bmfm.domain}")
    private String domain;

    @Value("${bmfm.filepath}")
    private String uri;

    @Value("${bmfm.tenantId}")
    private String tenantId;

    @Value("${bmfm.appKey}")
    private String appKey;

    @Value("${bmfm.appSecret}")
    private String appSecret;

    @Value("${bmfm.merge}")
    private String merge;

    @Value("${bmfm.codeTask}")
    private String codeTask;

    @Value("${bmfm.info}")
    private String info;

    @Resource(name = "restTemplateIgnoreSSL")
    private RestTemplate restTemplateIgnoreSSL;


    ObjectMapper objectMapper = new ObjectMapper();

    /*
    01
     */
    public GetFilepathRes getFilePath(GetFilepathReq req) {
        String url = domain + uri;
        String json = json(req);
        log.info("01请求获取上传地址的参数: " + json);
        log.info("请求地址: " + url);
        String res = HttpUtil.postBody(restTemplateIgnoreSSL, url, header(), json, String.class);
        log.info("01请求获取上传地址的响应结果: " + res);
        return object(res, GetFilepathRes.class);
    }

    public <T> T object(String s, Class<T> clazz) {
        try {
            return objectMapper.readValue(s, clazz);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("反序列化json发生异常");
        }

    }

    /*
    02
     */
    public void chunkUpload(String uri, byte[] file) {
        String url = domain + uri;
        log.info("02分片上传请求地址: " + url);
        HttpUtil.putBody(restTemplateIgnoreSSL, url, header(), file);
    }

    /*
    03
     */
    public void merge(String id) {
        String url = domain + String.format(merge, id);
        log.info("03分片合并请求地址: " + url);
        HttpUtil.put(restTemplateIgnoreSSL, url, header());
    }

    /*
    04
     */
    public String codeTask(String id) {
        String url = domain + codeTask;
        HashMap<String, Object> map = new HashMap<>();
        map.put("fileId", id);
        log.info("04赋码请求地址: " + url);
        String taskId = HttpUtil.postBody(restTemplateIgnoreSSL, url, header(), json(map), String.class);
        log.info("执行赋码操作的内部任务id： " + taskId);
        return taskId;
    }

    /*
    05
     */
    public FileInfoRes info(String filedId) {
        String url = domain + String.format(info, filedId);
        log.info("05获取文件请求地址: " + url);

        String s = HttpUtil.get(restTemplateIgnoreSSL, url, header(), String.class);
        log.info("05文件信息响应结果: " + s);
        return object(s, FileInfoRes.class);
    }

    /*
    06
     */
    public byte[] downLoad(String url) {
        log.info("06 分片下载");
        log.info("06 下载地址: " + url);
        return HttpUtil.getFile(restTemplateIgnoreSSL, url, header());
    }

    public void downLoad(String url, String filePath) {
        byte[] bytes = downLoad(url);
        try {
            Path path = Paths.get(filePath);
            Files.write(path, bytes);
        } catch (IOException e) {
            log.error("下载文件失败: " + e.getMessage());
        }
    }


    private HttpHeaders header() {
        HttpHeaders headers = new HttpHeaders();
        headers.set("X-TENANT-ID", tenantId);
        headers.set("X-App-Key", appKey);
        headers.set("X-App-Secret", appSecret);
        return headers;
    }

    public String json(Object val) {
        try {
            return objectMapper.writeValueAsString(val);
        } catch (JsonProcessingException e) {
            log.error("序列化json异常");
        }
        return null;
    }

}
